package interpreteur;

import interpreteur.action.ChaineFoncteur;
import interpreteur.echecs.Coups;
import interpreteur.action.Foncteur;
import interpreteur.action.Ou;
import interpreteur.action.Et;
import java.util.ArrayList;
import static interpreteur.echecs.Pieces.Piece.*;

public class FoncteurUtile extends Etat {

    

    public FoncteurUtile() {

        CaseSuivante = new Foncteur() {

            @Override
            public Result eval() {
                 pIndexDep++;
                return Result.NULL;
            }
        };

        DirSuivante = new Foncteur() {

            public Result eval() {
                pIndexDir++;
                return Result.NULL;
            }
        };
        DistSuivante = new Foncteur() {

            public Result eval() {
                pDist++;
                return Result.NULL;
            }
        };
        NewArrayListCoups = new Foncteur() {

            public Result eval() {
                pListeCoupsPart = new ArrayList<Coups>();
                return Result.NULL;
            }
        };

        InitDist = new Foncteur() {

            public Result eval() {
                pDist = 1;
                return Result.NULL;
            }
        };
        InitDir = new Foncteur() {

            public Result eval() {
                pIndexDir = 0;
                return Result.NULL;
            }
        };
        InitIndex = new ChaineFoncteur(InitDist, InitDir);

        AjoutCoupsListe = new Foncteur() {

            public Result eval() {
                pListeCoups.addAll(pListeCoupsPart);
                return Result.NULL;
            }
        };
        existeDirSuiv = new Foncteur() {

            public Result eval() {
                return new Result(pIndexDir < pPieceDep.getDeplacement().length);
            }
        };
        NewCoups = new Foncteur() {

            public Result eval() {
                pIndexArr = ECHIQUIER[TO_ECHIQUIER[pIndexDep] + pDist * pPieceDep.getDeplacement()[pIndexDir]];
                pListeCoupsPart.add(new Coups(pIndexDep, pPieceDep, pIndexArr));
                return Result.NULL;
            }
        };
        estPionDep = new Foncteur() {

            public Result eval() {
                return new Result(Case.valeur(pIndexDep).estARangee2() && pPieceDep.getCouleur() == Couleur.BLANC ||
                        Case.valeur(pIndexDep).estARangee7() && pPieceDep.getCouleur() == Couleur.NOIR);
            }
        };
        estFinDirPion = new Foncteur() {

            public Result eval() {
                return new Result(pIndexDir <= 2);
            }
        };
        estFouTourDame = new Foncteur() {

            public Result eval() {
                assert pPieceDep != null;
                return new Result(pPieceDep.equals(FOU_BLANC) || pPieceDep.equals(FOU_NOIR) ||
                        pPieceDep.equals(TOUR_BLANCHE) || pPieceDep.equals(TOUR_NOIRE) ||
                        pPieceDep.equals(DAME_BLANCHE) || pPieceDep.equals(DAME_NOIRE));

            }
        };
        estPion = new Foncteur() {

            public Result eval() {
                return new Result(pPieceDep.equals(PION_BLANC) || pPieceDep.equals(PION_NOIR));
            }
        };
        estRoiOuCavalier = new Foncteur() {

            public Result eval() {
                return new Result(pPieceDep.equals(ROI_BLANC) || pPieceDep.equals(ROI_NOIR) ||
                        pPieceDep.equals(CAVALIER_BLANC) || pPieceDep.equals(CAVALIER_NOIR));
            }
        };
        ExamineEchecs = new Foncteur() {

            public Result eval() {
                return new Result(_examineEchecs);
            }
        };
        PieceCouleurQuiJoue = new Foncteur() {

            public Result eval() {
                return new Result(pPieceDep != null && pPieceDep.getCouleur() == _couleur);
            }
        };
        ArrVide = new Foncteur() {

            public Result eval() {
                return new Result(ECHIQUIER[TO_ECHIQUIER[pIndexDep] +
                        pDist * pPieceDep.getDeplacement()[pIndexDir]] != -1 && PIECES[ECHIQUIER[TO_ECHIQUIER[pIndexDep] +
                        pDist * pPieceDep.getDeplacement()[pIndexDir]]] == null);
            }
        };
        PieceCouleurEtudiee = new Foncteur() {

            public Result eval() {
                pPieceDep = PIECES[pIndexDep];
                return new Result(pPieceDep != null && pPieceDep.getCouleur() == _couleur);
            }
        };
        existeCaseSuiv = new Foncteur() {

            public Result eval() {
                return new Result(pIndexDep < NB_COLONNES * NB_RANGEES);
            }
        };
        estCaseArrOccup = new Foncteur() {

            @Override
            public Result eval() {
                return new Result(ECHIQUIER[TO_ECHIQUIER[pIndexDep] +
                        pDist * pPieceDep.getDeplacement()[pIndexDir]] != -1 && PIECES[ECHIQUIER[TO_ECHIQUIER[pIndexDep] +
                        pDist * pPieceDep.getDeplacement()[pIndexDir]]] != null);
            }
        };
        PieceCouleurOpp = new Foncteur() {

            @Override
            public Result eval() {
                return new Result(pPieceDep.getCouleur() != PIECES[ECHIQUIER[TO_ECHIQUIER[pIndexDep] +
                        pDist * pPieceDep.getDeplacement()[pIndexDir]]].getCouleur());
            }
        };

        ArrOccup_PiecesCoulOpp = new Et(estCaseArrOccup, PieceCouleurOpp);
        ArrOccupEtPiecesCoulOpp = new Et(estCaseArrOccup, PieceCouleurOpp);
        ArrVideOu_ArrOccupEtPiecesCoulOpp = new Ou(ArrVide, ArrOccup_PiecesCoulOpp);
    }
}